package com.atguigu.gmall.order.receiver;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.enums.model.OrderStatus;
import com.atguigu.gmall.enums.model.ProcessStatus;
import com.atguigu.gmall.order.model.OrderInfo;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.payment.client.PaymentFeignClient;
import com.atguigu.gmall.payment.model.PaymentInfo;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.weaver.ast.Or;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * @author: atguigu
 * @create: 2023-01-28 14:23
 */
@Slf4j
@Component
public class OrderReceiver {

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private PaymentFeignClient paymentFeignClient;


    /**
     * 监听关闭订单消息：将订单关闭；todo 关闭本地交易记录，支付宝交易记录
     *
     * @param orderId 订单ID
     * @param message
     * @param channel
     */
    @RabbitListener(queues = {MqConst.QUEUE_ORDER_CANCEL})
    public void closeOrder(Long orderId, Message message, Channel channel) {
        try {
            //1.处理业务
            if (orderId != null) {
                log.info("【订单微服务】关闭订单消息：{}", orderId);
                //1.1 根据订单ID查询订单状态 状态如果是未支付：将订单状态改为关闭
                OrderInfo orderInfo = orderInfoService.getById(orderId);
                if (orderId != null && OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus()) && OrderStatus.UNPAID.name().equals(orderInfo.getProcessStatus())) {
                    //2.判断交易记录是否存在
                    PaymentInfo paymentInfo = paymentFeignClient.getPaymentInfo(orderId);
                    if (paymentInfo != null) {
                        //2.1 产生本地交易记录 要进行关闭
                        //2.2.发送关闭本地交易记录消息到MQ 通知支付微服务关闭本地交易记录
                        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE, MqConst.ROUTING_PAYMENT_CLOSE, orderId);

                        //3.查询支付宝交易记录是否关闭
                        Boolean flag = paymentFeignClient.checkPayment(orderId);
                        if(flag){
                            //3.1 支付宝交易以及产生 需要关闭
                            paymentFeignClient.closePay(orderId);
                        }else{
                            //3.2 支付宝交易没有产生 或者 以及关闭
                        }
                    }
                    //1.2 修改订单状态
                    orderInfoService.execExpiredOrder(orderId);
                }

            }
            //2.手动应答
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("【订单微服务】关闭订单业务异常：{}", e);
        }
    }


    /**
     * 监听支付成功后消息 1.更新订单状态  2.发送扣减库存消息
     *
     * @param orderId
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY),
            value = @Queue(MqConst.QUEUE_PAYMENT_PAY),
            key = {MqConst.ROUTING_PAYMENT_PAY}
    ))
    public void paySuccessUpdateOrder(Long orderId, Message message, Channel channel) {
        try {
            if (orderId != null) {
                log.info("【订单微服务】监听支付成功后消息，订单ID：{}", orderId);
                //1.修改订单状态为 已支付
                OrderInfo orderInfo = orderInfoService.getById(orderId);
                if (orderInfo != null && !OrderStatus.PAID.name().equals(orderInfo.getOrderStatus())) {
                    orderInfoService.updateOrderStatus(orderId, ProcessStatus.PAID);
                    //2.发送扣减库存消息到MQ 通知 仓库系统
                    orderInfoService.sendDeductStockMsg(orderId);
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("【订单微服务】 处理修改订单发送消息异常：{}", e);
        }
    }


    /**
     * 监听到库存系统扣减库存结果，修改订单状态
     *
     * @param stockJsonStr {"orderId":1,"satuts":"DEDUCTED"}
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(MqConst.EXCHANGE_DIRECT_WARE_ORDER),
            value = @Queue(MqConst.QUEUE_WARE_ORDER),
            key = MqConst.ROUTING_WARE_ORDER
    ))
    public void processDeductStockResult(String stockJsonStr, Message message, Channel channel) {
        try {
            if (StringUtils.isNotBlank(stockJsonStr)) {
                log.info("【订单微服务】监听到库存系统扣减库存结果：{}", stockJsonStr);
                //1.将扣减库存结果转为Map 得到订单ID以及扣款库存结果
                Map map = JSON.parseObject(stockJsonStr, Map.class);
                String orderId = (String) map.get("orderId");
                String status = (String) map.get("status");
                //2.根据结果更新订单状态
                if ("DEDUCTED".equals(status)) {
                    //扣减成功
                    orderInfoService.updateOrderStatus(Long.parseLong(orderId), ProcessStatus.WAITING_DELEVER);
                } else {
                    //扣减失败-方案：提供定时任务扫描订单中处理状态为：库存异常。将这些订单作为预警订单提醒工作人员处理
                    orderInfoService.updateOrderStatus(Long.parseLong(orderId), ProcessStatus.STOCK_EXCEPTION);
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("【订单微服务】处理扣减库存结果异常：{}", e);
        }
    }


}
